package com.demo2do.fms.admin.web.controller.supplier.management;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.page.Page;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.interceptor.MenuSetting;
import com.demo2do.core.web.resolver.Preloading;
import com.demo2do.core.web.utils.WebUtils;
import com.demo2do.fms.admin.entity.search.supplier.DriverSearch;
import com.demo2do.fms.admin.entity.security.Login;
import com.demo2do.fms.admin.entity.upload.UploadResult;
import com.demo2do.fms.admin.entity.vam.DriverStat;
import com.demo2do.fms.admin.service.supplier.DriverService;
import com.demo2do.fms.admin.service.supplier.SupplierService;
import com.demo2do.fms.admin.web.resolver.Secure;
import com.demo2do.fms.entity.driver.Driver;
import com.demo2do.fms.entity.driver.DriverAuditStatus;
import com.demo2do.fms.entity.supplier.common.Supplier;
import com.demo2do.fms.entity.vam.DriverLine;

/**
 * 司机信息管理
 *
 * @author Ark
 *
 */
@Controller
@RequestMapping("/drivers")
@MenuSetting("menu-supplier")
public class DriverController {
    
    private static final Logger logger = LoggerFactory.getLogger(DriverController.class);
    
    @Autowired
    private DriverService driverService;
    
    @Autowired
    private SupplierService supplierService;
    
    /**
     * 司机列表页
     * 
     * @param login
     * @param status
     * @param driverUploadResults
     * @param request
     * @param page
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @MenuSetting("submenu-self-driver-management")
    public ModelAndView list(@Secure Login login,
                             @RequestParam(name = "status", required = false, defaultValue = "EDITING") DriverAuditStatus status,
                             @RequestParam(name = "driverUploadResults", required = false) String driverUploadResults,
                             HttpServletRequest request, Page page) {

        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-list");
        
        int totals = driverService.count(login, status);
        if (totals > 0) {

            List<Driver> drivers = driverService.list(login, status, page.with(totals));
            modelAndView.addObject("drivers", drivers);
            
            modelAndView.addObject("page", page);
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page", "filter"));
            
        }
        
        modelAndView.addObject("supplier", login.isSupplier());
        modelAndView.addObject("status", status);
        
        if (StringUtils.isNotBlank(driverUploadResults)) {
            modelAndView.addObject("driverUploadResults", JsonUtils.parseAsList(driverUploadResults, UploadResult.class));
        }

        return modelAndView;
        
    }
    
    /**
     * 过滤查询
     * 
     * @param status
     * @return
     */
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    @MenuSetting("submenu-self-driver-management")
    public ModelAndView search(@RequestParam(name = "status") DriverAuditStatus status) {

        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-search");
        
        modelAndView.addObject("status", status);

        return modelAndView;
        
    }
    
    /**
     * 过滤查询
     * 
     * @param login
     * @param driverSearch
     * @param request
     * @param page
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-self-driver-management")
    public ModelAndView onSearch(@Secure Login login,
                                 DriverSearch driverSearch, 
                                 HttpServletRequest request, 
                                 Page page) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-list");
        
        if (login.isSupplier()) {
            driverSearch.setSupplierId(login.getSupplierId());
        }
        
        int totals = driverService.count(driverSearch);
        if (totals > 0) {
            
            List<Driver> drivers = driverService.list(driverSearch, page.with(totals));
            
            modelAndView.addObject("drivers", drivers);
            modelAndView.addObject("page", page);
            modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page", "filter"));
            
        }

        modelAndView.addObject("supplier", login.isSupplier());
        modelAndView.addObject("status", driverSearch.getStatus());
        
        return modelAndView;
        
    }
    
    /**
     * 判断司机工号是否存在
     * 
     * @param code
     * @return
     */
    @RequestMapping(value = "/exist-code", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult existByCode(@RequestParam("code") String code) {
        
        HttpResult httpResult = new HttpResult();
        
        try {

            Map<String, Object> result = driverService.existCode(code);
            boolean existed = (boolean) result.get("existed");
            String message = (String) result.get("message");
            
            httpResult.success().data("existed", existed)
                                .data("message", message)
                                .message("根据工号查询司机是否存在成功");
            
        } catch (Exception e) {
            logger.error("#exist() - occur exception [{}]", e);
            httpResult.fail("500").message("根据工号查询司机是否存在失败!");
        }
        
        return httpResult;
        
    }
    
    /**
     * 判断司机身份证号是否存在
     * 
     * @param citizenCode
     * @return
     */
    @RequestMapping(value = "/exist-citizen", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult existByCitizen(@RequestParam("citizenCode") String citizenCode) {
        
        HttpResult httpResult = new HttpResult();
        
        try {

            Map<String, Object> result = driverService.existCitizen(citizenCode);
            boolean existed = (boolean) result.get("existed");
            String message = (String) result.get("message");
            
            httpResult.success().data("existed", existed)
                                .data("message", message)
                                .message("根据身份证号查询司机是否存在成功");
            
        } catch (Exception e) {
            logger.error("#exist() - occur exception [{}]", e);
            httpResult.fail("500").message("根据身份证号查询司机是否存在失败!");
        }
        
        return httpResult;
        
    }
    
    /**
     * 判断司机手机号是否已存在
     * 
     * @param mobile
     * @return
     */
    @RequestMapping(value = "/exist-mobile", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult existByMobile(@RequestParam("mobile") String mobile) {
        
        HttpResult httpResult = new HttpResult();
        
        try {

            Map<String, Object> result = driverService.existMobile(mobile);
            boolean existed = (boolean) result.get("existed");
            String message = (String) result.get("message");
            
            httpResult.success().data("existed", existed)
                                .data("message", message)
                                .message("根据手机号查询司机是否存在成功");
            
        } catch (Exception e) {
            logger.error("#exist() - occur exception [{}]", e);
            httpResult.fail("500").message("根据手机号查询司机是否存在失败!");
        }
        
        return httpResult;
        
    }
    
    /**
     * 根据中文车牌号获取司机信息
     * 
     * @param brandCNCode
     * @return
     */
    @RequestMapping(value = "/query", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "brandCNCode")
    public @ResponseBody HttpResult queryByBrand(@RequestParam("brandCNCode") String brandCNCode) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            List<DriverStat> driverStats = driverService.listByBrand(brandCNCode);
            
            httpResult.success().data("drivers", driverStats)
                                .message("查询成功");
            
        } catch (Exception e) {
            logger.error("#queryByBrand() - occur exception [{}]", e);
            httpResult.fail("500").message("查询失败");
        }
        
        return httpResult;
        
    }
    
    /**
     * 根据批量中文车牌号获取司机信息
     * 
     * @param brandCNCodes
     * @return
     */
    @RequestMapping(value = "/query", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, params = "brandCNCodes")
    public @ResponseBody HttpResult queryByBrand(@RequestParam("brandCNCodes") List<String> brandCNCodes) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            logger.warn("#queryByBrand() - brandCNCodes size = {}", CollectionUtils.size(brandCNCodes));
            
            if (CollectionUtils.size(brandCNCodes) > 200) {
                return httpResult.fail("1").message("查询失败！车牌号数量不合格");
            }
            
            List<DriverLine> driverLines = driverService.listByBrand(brandCNCodes);
            
            httpResult.success().data("drivers", driverLines)
                                .message("查询成功");
            
        } catch (Exception e) {
            logger.error("#queryByBrand() - occur exception [{}]", e);
            httpResult.fail("1").message("查询失败");
        }
        
        return httpResult;
        
    }
    
    /**
     * 新增司机
     * 
     * @param login
     * @return
     */
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    @MenuSetting("submenu-self-driver-management")
    public ModelAndView create(@Secure Login login) {
        
        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-create");
        
        Supplier supplier = supplierService.load(Supplier.class, login.getSupplierId());
        modelAndView.addObject("organizationId", supplier.getOrgId());
        
        return modelAndView;
        
    }

    /**
     * onCreate
     *
     * @param login
     * @param driver
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onCreate(@Secure Login login, Driver driver) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            driverService.create(driver, login);
            
            httpResult.success().message("创建成功");
            
        } catch (Exception e) {
            logger.error("#onCreate() - create driver occur exception [{}]", e);
            httpResult.fail("500").message("创建失败! " + e.getMessage());
        }
        
        return httpResult;
        
    }

    /**
     * 批量导入
     * 
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.GET)
    public ModelAndView upload() {
        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-upload");
        return modelAndView;
    }
    
    /**
     * 批量导入 - 执行
     * 
     * @param login
     * @param file
     * @param attributes
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ModelAndView onUpload(@Secure Login login,
                                 @RequestParam("file") MultipartFile file,
                                 RedirectAttributes attributes) {
    
        ModelAndView modelAndView = new ModelAndView("redirect:/drivers");
        
        List<UploadResult> driverUploadResults = driverService.upload(login, file);
        
        if (CollectionUtils.isNotEmpty(driverUploadResults) && CollectionUtils.size(driverUploadResults) < 20) {
            
            attributes.addAttribute("driverUploadResults", JsonUtils.toJson(driverUploadResults, UploadResult.class));
            
        } else if (CollectionUtils.isNotEmpty(driverUploadResults) && CollectionUtils.size(driverUploadResults) >= 20) {
            
        	driverUploadResults = driverUploadResults.subList(0, 20);
        	attributes.addAttribute("driverUploadResults", JsonUtils.toJson(driverUploadResults, UploadResult.class));
        	
        }
        
        return modelAndView;
        
    }
    
    /**
     * 删除
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/delete", method = RequestMethod.GET)
    @MenuSetting("submenu-self-driver-management")
    public ModelAndView delete(@PathVariable("id") Long id) {

        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-delete");

        modelAndView.addObject("id", id);

        return modelAndView;
        
    }

    /**
     * 删除
     *
     * @param operator
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onDelete(@Secure(property = "id") Long operator,
                                             @PathVariable("id") Long id) {

        HttpResult httpResult = new HttpResult();

        try {
            
            driverService.delete(id, operator);
            httpResult.success().message("删除成功");
            
        } catch (Exception e) {
            logger.error("#onDelete() delete driver occur exception [{}]", e);
            httpResult.fail("500").message("删除失败");
        }

        return httpResult;

    }
    
    /**
     * 递交审核panel
     *  
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/audit", method = RequestMethod.GET)
    public ModelAndView audit(@PathVariable("id") Long id) {

        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-audit");

        modelAndView.addObject("id", id);

        return modelAndView;
        
    }

    /**
     * 递交审核
     * 
     * @param login
     * @param driver
     * @return
     */
    @RequestMapping(value = "/{id}/audit", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onAudit(@Secure Login login, @Preloading("id") Driver driver) {

        HttpResult httpResult = new HttpResult();

        try {
            
            driverService.audit(driver, login);
            httpResult.success().message("递交审核成功");
            
        } catch (BusinessException e) {
            logger.error("#onAudit - audit driver fail, exception is [{}]", e);
            httpResult.fail("500").message(e.getMessage());
        }catch (Exception e) {
            logger.error("#onAudit - audit driver fail, exception is [{}]", e);
            httpResult.fail("500").message("递交审核失败");
        }

        return httpResult;

    }
    
    /**
     * 批量递交审核panel
     * 
     * @return
     */
    @RequestMapping(value = "/batch-audit", method = RequestMethod.GET)
    public ModelAndView batchAudit() {
        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-batch-audit");
        return modelAndView;
    }
    
    /**
     * 批量递交审核
     * 
     * @param login
     * @param driverIds
     * @return
     */
    @RequestMapping(value = "/batch-audit", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onBatchAudit(@Secure Login login, @RequestParam("driverIds") List<Long> driverIds) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            Map<String, Integer> result = driverService.batchAudit(driverIds, login);
            
            int successNumber = result.get("successNumber");
            int failNumber = result.get("failNumber");
            
            if (successNumber == 0) {
                httpResult.fail("").message("批量递交审核全部失败");
            } else {
                httpResult.success().message("批量递交审核结果，成功条数=" + successNumber + "。失败条数=" + failNumber);
            }
            
        } catch (Exception e) {
            logger.error("#onBatchAudit - batch audit driver fail, exception is [{}]", e);
            httpResult.fail("500").message("批量递交审核失败," + e.getMessage());
        }
        
        return httpResult;
        
    }
    
    /**
     * 离职panel
     *  
     * @param id
     * @return
     */
    @RequestMapping(value = "/{id}/quit", method = RequestMethod.GET)
    public ModelAndView quit(@PathVariable("id") Long id) {

        ModelAndView modelAndView = new ModelAndView("supplier/management/driver/driver-quit");

        modelAndView.addObject("id", id);

        return modelAndView;
        
    }

    /**
     * 离职
     * 
     * @param login
     * @param driver
     * @return
     */
    @RequestMapping(value = "/{id}/quit", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onQuit(@Secure Login login, @Preloading("id") Driver driver) {

        HttpResult httpResult = new HttpResult();

        try {
            
            driverService.quit(driver, login);
            
            httpResult.success().message("离职成功");
            
        } catch (Exception e) {
            logger.error("#onQuit() - quit driver occur exception [{}]", e);
            httpResult.fail("500").message("离职失败！" + e.getMessage());
        }

        return httpResult;

    }
    
}